package com.zeekr.orm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 吴文杰
 * @version 1.0
 * @since 2024/7/11 0:30
 * <p>
 * <p>
 * 1. 调用线程
 * 非核心线程是否存活，存活直接执行，非存活先放入队列，队列满后再使用非核心线程执行.
 * <p>
 * 2. 拒绝策略
 * AbortPolicy  队列满后后舍弃任务,报异常.
 * CallerRunsPolicy  队列满后再调用者线程执行任务，如果执行线程关闭，则舍弃任务.
 * <p>
 * DiscardPolicy  队列满后舍弃任务，什么都不做.
 * DiscardOldestPolicy  队列满后舍弃最旧的任务.
 */
@Configuration
public class ThreadPoolExecutorConfig {

  @Bean
  public ThreadPoolExecutor getThreadPoor() {

    ThreadFactory threadFactory = new ThreadFactory() {
      private int count = 1;

      @Override
      public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("get线程" + (count++));
        return thread;
      }
    };
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100,
            TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), threadFactory,
            new ThreadPoolExecutor.CallerRunsPolicy());
    threadPoolExecutor.allowCoreThreadTimeOut(false);

    return threadPoolExecutor;
  }

  @Bean
  public ThreadPoolExecutor postThreadPoor() {
    ThreadFactory threadFactory = new ThreadFactory() {
      private int count = 1;

      @Override
      public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("post线程" + (count++));
        return thread;
      }
    };
    return new ThreadPoolExecutor(2, 5, 100,
            TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), threadFactory,
            new ThreadPoolExecutor.AbortPolicy());
  }

  @Bean
  public ThreadPoolExecutor loginThreadPoor() {
    ThreadFactory threadFactory = new ThreadFactory() {
      private int count = 1;

      @Override
      public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("login线程" + (count++));
        return thread;
      }
    };
    return new ThreadPoolExecutor(2, 6, 8000,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(5),
            threadFactory,
            new ThreadPoolExecutor.AbortPolicy());
  }

}
